/**
 * 
 */
package cn.com.gzheroli.util.gencode;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.core.resource.FileResourceLoader;
import org.beetl.sql.core.ClasspathLoader;
import org.beetl.sql.core.ConnectionSource;
import org.beetl.sql.core.ConnectionSourceHelper;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.SQLLoader;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.UnderlinedNameConversion;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.core.db.OracleStyle;
import org.beetl.sql.core.db.TableDesc;
import org.beetl.sql.core.kit.GenKit;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.ext.gen.GenConfig;
import org.beetl.sql.ext.gen.GenFilter;

import cn.com.gzheroli.core.util.NameUtils;
import cn.com.gzheroli.herojdbc.CodeResourceUtil;
import cn.com.gzheroli.util.gencode.pojo.Columnt;


/**  
* @类名: BeetlGenerator  
* @描述: TODO(这里用一句话描述这个类的作用)  
* @作者: 李长荣 lichang_20011@163.com  
* @日期: 2017年10月17日  下午2:02:56
*@version V1.0  
*    
*/
public class BeetlGenerator {
	private static final Log log = LogFactory.getLog(BeetlGenerator.class);
	private static  String entityPackage = "cn.com.gzheroli.workflow.pojo.activiti";
	  private  String entityName = "";
	  private  String ftlDescription = "";
	  private List<Columnt> originalColumns = new ArrayList();
	  private List<Columnt> columns = new ArrayList();
	  private ReadTable dbFiledUtil = new ReadTable();
	/**
	 * @throws Exception 
	 * @throws SQLException 
	 * @throws IOException  
	* @Title: main 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param args    设定文件 
	* @return void    返回类型 
	* @throws 
	*/
	public static void main(String[] args) throws Exception { 
		
		String root = System.getProperty("user.dir")+File.separator+"src/main/resources/sql";//模板路径
	      FileResourceLoader resourceLoader = new FileResourceLoader(root,"utf-8");
	      Configuration cfg = Configuration.defaultConfiguration();
	      GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
	      BeetlGenerator t = new BeetlGenerator();
	      //t.getCodeForBean(gt, "/entity.md","ACT_");//
	}
	public static void genCode(String templatePath,String templateName,String dbType,Map paraMap) {
		String root = System.getProperty("user.dir")+File.separator+"src/main/resources/sql";//模板路径
	      //FileResourceLoader resourceLoader = new FileResourceLoader(templatePath,"utf-8");
	      ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader(templatePath==null?"template":templatePath,"utf-8");
		try {
			Configuration cfg = Configuration.defaultConfiguration();
			GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
		      BeetlGenerator t = new BeetlGenerator();
		      t.getCodeForBean(gt, templateName,dbType,paraMap);//
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	      
	}
	public Map<String, Object> genBeanMap(String tableName,Map paraMap){
		  ftlDescription=this.dbFiledUtil.getTableComment(tableName);
		  entityName=NameUtils.underscore2camel(tableName);
		  entityName=StringUtils.capitalize(entityName);
	    Map<String,Object> data = new HashMap<String,Object>();
	    data.put("bussiPackage", paraMap.get("bussiPackage")==null?CodeResourceUtil.bussiPackage:paraMap.get("bussiPackage"));	    
	   data.put("bussiWebPackage", paraMap.get("bussiWebPackage")==null?CodeResourceUtil.bussiWebPackage:paraMap.get("bussiWebPackage"));	    
	    data.put("sourceMainPath", paraMap.get("source_main_path")==null?CodeResourceUtil.source_main_path:paraMap.get("source_main_path"));
	    String entityPackage=paraMap.get("entityPackage")==null?"pojo":paraMap.get("entityPackage").toString();//cn.com.gzheroli.hoa.
	    data.put("entityPackage", entityPackage);
	    data.put("entityName", entityName);
	    data.put("tableName", tableName);
	    data.put("description", ftlDescription);
	    data.put("create_time", CodeDateUtils.dateToString(new Date()));
	    try
	    {
	      this.columns = this.dbFiledUtil.readTableColumn(tableName);
	      data.put("columns", this.columns);

	      this.originalColumns = this.dbFiledUtil.readOriginalTableColumn(tableName);
	      data.put("originalColumns", this.originalColumns);

	      for (Columnt c : this.originalColumns) {
	        if (c.getFieldName().toLowerCase().equals(CodeResourceUtil.GENERATE_TABLE_ID.toLowerCase()))
	          data.put("primary_key_type", c.getFieldType());
	      }
	    }
	    catch (Exception e)
	    {
	      e.printStackTrace();
	      System.exit(-1);
	    }
	    return data;
	  }
	public static  void saveSourceFile(SQLManager sqlManager,String srcPath,String pkg,String className,String content) throws IOException{
		
		final TableDesc  tableDesc = sqlManager.getMetaDataManager().getTable(className);
		 className = sqlManager.getNc().getClassName(tableDesc.getName());
		String file = srcPath+File.separator+pkg.replace('.',File.separatorChar);
		File f  = new File(file);
		f.mkdirs();
		File target = new File(file,className+".java");
		FileWriter writer = new FileWriter(target);
		writer.write(content);;
		writer.close();
	}
	/**
	   * 
	   * @param gt
	   * @param FilePath 模板路径
	 * @throws Exception 
	   */

	  private void getCodeForBean(GroupTemplate gt,String FilePath,String dbType,Map paraMap) throws Exception{
	      Template t = gt.getTemplate(FilePath);
	      String tablePre=paraMap.get("tablePre")==null?"":paraMap.get("tablePre").toString();
	      ConnectionSource source = ConnectionSourceHelper.getSimple(CodeResourceUtil.DIVER_NAME, CodeResourceUtil.URL, "", CodeResourceUtil.USERNAME, CodeResourceUtil.PASSWORD);
			DBStyle dbStyle = null;
			if(dbType.equals("mysql"))
			dbStyle=new MySqlStyle();
			if(dbType.equals("oracle"))
				dbStyle=new OracleStyle();
			// sql语句放在classpagth的/sql 目录下
			SQLLoader loader = new ClasspathLoader("/sql");
			// 数据库命名跟java命名一样，所以采用DefaultNameConversion，还有一个是UnderlinedNameConversion，下划线风格的
			UnderlinedNameConversion nc = new  UnderlinedNameConversion();
			// 最后，创建一个SQLManager,DebugInterceptor 不是必须的，但可以通过它查看sql执行情况
			SQLManager sqlManager = new SQLManager(dbStyle,loader,source,nc,new Interceptor[]{new DebugInterceptor()});
		    List<String> tableNames=this.dbFiledUtil.readAllTableNames();
			  for(String tableName:tableNames){//"T_B_"
				  if(tableName.indexOf(tablePre)==-1)
					  continue;
				  log.info("-------Code----Generation----[单表模型:" + tableName + "]------- 生成中。。。");
				  t.binding("bean",genBeanMap(tableName,paraMap));
			      String str = t.render();
			     // System.out.println(str);//打印出生成的代码
			      //String srcPath,String pkg,String className,String content
			      String srcPath = GenKit.getJavaSRCPath();
			      String pkg=paraMap.get("pkg")==null?"cn.com.gzheroli.workflow.pojo.activiti":paraMap.get("pkg").toString();
			      this.saveSourceFile(sqlManager,srcPath,pkg,tableName,str);
			     // GenConfig genConfig = new GenConfig();
					//genConfig.setPreferDate(true);
					//genConfig.initTemplate("/sql");
					//sqlManager.genPojoCode(tableName, "cn.com.gzheroli.test","/sql", genConfig);
					/*sqlManager.genALL("cn.com.gzheroli.test", genConfig, new GenFilter() {
						public boolean accept(String tableName) {
							if (tableName.startsWith("ACT_")) {
								return true;
							} else {
								return false;
							}
						}
					});*/
				    log.info("--------Code----Generation-----[单表模型：" + tableName + "]------ 生成完成。。。");
			  }
	      
	  }


}
